local handler = require "handler"
local util = require "util"
local utils = require "utils"
local reason = require "reason"
local error_code = require "error_code"
local constant = require "constant"
local cocall = require "cocall"
local game_def = require "game_def"
local tree_def = require "tree_def"
local dbdata = require "dbdata"
local cjson         = require "cjson"

local table_insert = table.insert
local table_sort = table.sort
local math_floor = math.floor
local math_random  = math.random

local tostring = tostring

local notify_money_changed = handler.notify_money_changed

local tree_handler = {}

--重置摇钱树任务
function reset_tree_task(tree_info)
    local task_info = tree_info.task_info
    
    task_info:clear_from_array()
    local task_def = global_configs.tree_task or {}
    for _,v in pairs(task_def) do
        local task_item = task_info:new_table_field(#task_info +1)
        task_item.tree_task_id = v.tree_task_id   --任务id
        task_item.param = 0     --任务进度
        task_item.status = 0      --任务状态
    end
    tree_info.rewarded = false    --是否已经奖励摇钱次数
    tree_info.shake_count = 0           --摇钱次数
    tree_info.reward_status = 0         --完成所有任务奖励状态
    -- dbglog("reset_tree_task",tree_info)
end

--获取任务信息
function get_task_item(task_info,task_id)
    for _,v in pairs(task_info) do
        if v.tree_task_id == task_id then
            return v
        end
    end
    errlog("get_task_item",task_id,task_info)
    return {}
end

--获取任务配置
function get_task_conf(task_id)
    local task_def = global_configs.tree_task or {}
    for _,v in pairs(task_def) do
        if v.tree_task_id == task_id then
            return v
        end
    end
    return {}
end

--检测摇钱树任务 （后台任务增删）
function check_reload_tree_task(tree_info)
    local task_info = tree_info.task_info
    local task_def = global_configs.tree_task or {}
    -- dbglog(task_def)
    for _,v in pairs(task_def) do
        local task_item = get_task_item(task_info,v.tree_task_id)
        -- dbglog(task_item)
        --有新增摇钱树任务
        if not task_item.tree_task_id then
            local item = task_info:new_table_field(#task_info +1)
            item.tree_task_id = v.tree_task_id
            item.param = 0
            item.status = 0
            dbglog("add task",v.tree_task_id)
        end
    end 


    for i = #task_info,1,-1 do
        local item_conf = get_task_conf(task_info[i].tree_task_id)
        --有任务被删除
        if not item_conf.tree_task_id then
            task_info:remove_from_array(i)
        end
    end

end

--获取摇钱树等级对应配置
function get_tree_level_item(conf,lv)
    for _,v in pairs(conf) do
        if v.level == lv then
            return v
        end
    end
    return nil
end

--校验是否有摇钱前置任务没有完成
function check_task(task_info)
    for _,v in pairs(task_info) do
        local tree_task_item = get_task_conf(v.tree_task_id)
        if v.status ~= 2 and not tree_task_item.shake_key then
            return false
        end
    end

    return true
end

--获取随机摇钱奖励
function get_reward(rewards)
    local weight = 0
    for _,v in pairs(rewards) do
        weight = weight + v[2] 
    end
    local rand = math_random(weight)

    dbglog(rewards,rand)
    weight = 0
    for _,v in pairs(rewards) do
        weight = weight + v[2]
        if rand <= weight then
            return v[1]
        end
    end
    return 0
end

--获取最大的奖励
function get_max_reward(rewards)
    rewards = rewards or {}
    local temp = 0
    for _,v in pairs(rewards) do
        if v[1] > temp then
            temp = v[1]
        end
    end
    return temp
end

--获取任务信息
function get_task_items(task_info,task_type)
    local items = {}
    for _,v in pairs(task_info) do
        local task_conf = get_task_conf(v.tree_task_id)
        if task_type == task_conf.tree_task_type then
            table_insert(items,v)
        end
    end

    return items
end

--同步摇钱树信息变化
function ntf_tree_info(tree_info,add_exp,add_fertilizer)
    local tree_level_conf = global_configs.tree_level or {}
    local tree_item = get_tree_level_item(tree_level_conf,tree_info.level)
    local next_tree_level = get_tree_level_item(tree_level_conf,tree_info.level + 1) or {}

    local res = {
        level = tree_info.level,
        exp = tree_info.exp,
        max_exp = next_tree_level.exp or 0,
        add_exp = add_exp,
        add_fertilizer = add_fertilizer,
        max_rewards = get_max_reward(tree_item.rewards),
        tree_url = tree_item.tree_url,
        shake_count = tree_info.shake_count,
        reward_coins = tree_item.coins,
        reward_status = tree_info.reward_status,
    }
    -- dbglog(res)
    send_to_gateway('tree.NTF_TREE_INFO',res)
end


--更新摇钱树信息
function update_tree_info(tree_info)
    local tree_level_conf = global_configs.tree_level or {}
    local tree_item = get_tree_level_item(tree_level_conf,tree_info.level + 1)

    if tree_item and tree_item.exp <= tree_info.exp then
        local tree_item_begin = get_tree_level_item(tree_level_conf,tree_info.level)

        tree_info.exp = tree_info.exp - tree_item.exp
        tree_info.level = tree_info.level + 1

        if not update_tree_info(tree_info) then
            return tree_info.level
        end
    end
    return false
end

--获得任务信息
function get_client_task_item(task_item,task_conf)
    local item = {}
    item.id = task_item.tree_task_id
    item.status = task_item.status
    item.param = task_item.param
    item.rewards = task_conf.fertilizer
    item.content = task_conf.content
    item.param_max = task_conf.param
    item.task_type = task_conf.tree_task_type  

    if item.task_type == constant.TREE_TASK_TYPE.WATER then
        item.param = math_floor(item.param/100)
        item.param_max = math_floor(item.param_max/100)
    end
    return item
end

--完成任务
function finish_tree_task(tree_info,task_type,param,key,info)
    local task_items = get_task_items(tree_info.task_info,task_type)
    dbglog(task_items,task_type)
    for _,task_item in pairs(task_items) do
        if task_item.status == 0 then
            local task_conf = get_task_conf(task_item.tree_task_id)   
            if key then
                task_item.param = param
            else    
                task_item.param = task_item.param + param
            end
            if task_item.param >= task_conf.param then
                task_item.param = task_conf.param 
                task_item.status = 1
            end

            --返回任务信息
            if info then
                local item = get_client_task_item(task_item,task_conf)
                table_insert(info, item)
            end
        end
    end

    for _,v in pairs(tree_info.task_info) do
        if v.status == 0 then
            return
        end
    end 
    if tree_info.reward_status == 0 then
        tree_info.reward_status = 1 
    end 
end

--检测红点
function check_red_points(tree_info,module_list)
    if not tree_info.shake_count then
        reset_tree_task(tree_info)
    end

    dbglog(tree_info,module)
    if tree_info.shake_count > 0 then
        table_insert(module_list,constant.MODULE_DEF.TREE)
        return true
    end

    if tree_info.reward_status == 1 then
        table_insert(module_list,constant.MODULE_DEF.TREE)
        return true
    end

    return false
end

--添加操作记录
function add_record(records,type,add_exp,up_lv)
    local item = records:new_table_field(#records +1)
    item.time = util.get_now_time()
    item.add_exp = add_exp
    if up_lv then
        item.up_lv = up_lv
    end
    item.type = type
    if #records > 50 then
        records:remove_from_array(1)
    end
    -- dbglog(records)
end

--当天新增下级人数
function check_daili(player)
    local uid = player.uid
    local status, body = handler.common_post(constant.TREE_TASK_DAILI, {})
    if status == 200 then
        local tree_info = player.user_data.tree_info
        check_reload_tree_task(tree_info)
        local body = cjson.decode(body)
        finish_tree_task(tree_info,constant.TREE_TASK_TYPE.SUBORDINATES,tonumber(body.result.subnum),true)
        return true
    end
    errlog("TREE_TASK_DAILI status:",status)
    return false
end

--活动人数统计
function activity_player_number(uid)
    local data = {}
    data.uid = uid
    data.type = constant.DODULE_ID.MONEY_TREE 
    data.key = ""..os.date("%Y%m%d%H%M%S") .."_".. data.type .. "_" .. math.random(1,10000)
    data.op = "partake_num"
    dbglog("_____opPartakeNum__", dump(data))
    billlog(data)
end

--摇一摇
function tree_handler.REQ_SHAKE_TREE(msg)
    local uid = player.uid
    local tree_info = player.user_data.tree_info
    check_reload_tree_task(tree_info)
    local tree_level_conf = global_configs.tree_level or {}
    local tree_item = get_tree_level_item(tree_level_conf,tree_info.level)

    if tree_info.shake_count <= 0 then
        send_to_gateway('tree.RSP_SHAKE_TREE', {result = error_code.RSP_SUCESS})
        return true
    end

    local coins = get_reward(tree_item.rewards)
    local exinfo = {channel = player.channel,cur_channel = player.cur_channel}
    local ok,succ,ret = R().basesvr({key=uid}):call('.msg_handler','add_coins',uid,coins,reason.TREE,exinfo)
    if ok and succ and ret then
        tree_info.shake_count = tree_info.shake_count - 1
        notify_money_changed(uid,{coins = ret.curr})
    end
    activity_player_number(uid)
    send_to_gateway('tree.RSP_SHAKE_TREE', {result = error_code.RSP_SUCESS,coins = coins,count = tree_info.shake_count})
    return true
end

--请求摇钱树信息
function tree_handler.REQ_TREE_INFO(msg)
    local tree_info = player.user_data.tree_info
    check_reload_tree_task(tree_info)
    check_daili(player)
    local tree_level_conf = global_configs.tree_level or {}
     update_tree_info(tree_info)   
    if check_task(tree_info.task_info) and not tree_info.rewarded then
        local item = get_tree_level_item(tree_level_conf,tree_info.level)
        tree_info.shake_count = item.shake_count
        tree_info.rewarded = true
    end

    local tree_item = get_tree_level_item(tree_level_conf,tree_info.level)
    local next_tree_level = get_tree_level_item(tree_level_conf,tree_info.level + 1)
    next_tree_level = next_tree_level or {}
    tree_item = tree_item or {}
    local tree_pic = global_configs.tree_pic or {}
    local tree_conf = global_configs.tree_conf or {}
    local info = {}
    local images = {}
    for _,v in pairs(tree_info.task_info) do
        local task_conf = get_task_conf(v.tree_task_id)
        local item = get_client_task_item(v,task_conf)
        table_insert(info,item)
    end

    for _,v in pairs(tree_pic) do
        table_insert(images,v)
    end

    local data = {
        level = tree_info.level,
        exp = tree_info.exp,
        shake_count = tree_info.shake_count,
        reward_status = tree_info.reward_status,
        max_exp = next_tree_level.exp,
        max_rewards = get_max_reward(tree_item.rewards),
        info = info,
        image_urls = images,
        fertilizer_rate = tree_conf.fertilizer_rate,
        reward_coins = tree_item.coins,
        shake_tips = tree_conf.shake_tips,
        tree_url = tree_item.tree_url,
    }
    dbglog(tree_info.task_info,data)
    return send_to_gateway('tree.RSP_TREE_INFO', data)
end

--领取任务奖励
function tree_handler.REQ_TASK_REWARD(msg)
    local tree_info = player.user_data.tree_info  
    check_reload_tree_task(tree_info)
    local task_id = msg.task_id
    local task_conf = get_task_conf(task_id)
    local fertilizer = task_conf.fertilizer
    local tree_conf = global_configs.tree_conf or {}
    local fertilizer_rate = tree_conf.fertilizer_rate 
    local tree_level_conf = global_configs.tree_level or {}
    local tree_item = get_tree_level_item(tree_level_conf,tree_info.level)

    local task_item = get_task_item(tree_info.task_info,task_id)

    if task_item.status ~= 1 then
        return send_to_gateway('tree.RSP_TASK_REWARD', {result = error_code.RSP_SUCESS})
    end

    task_item.status = 2

    local add_exp = fertilizer*fertilizer_rate

    tree_info.exp = tree_info.exp + add_exp
    local level = tree_info.level
    local up_lv = update_tree_info(tree_info) 
    dbglog("level",level,"up_lv",up_lv,"tree_info.level",tree_info.level)
    if level ~= tree_info.level then
        up_lv = tree_info.level
    end
    add_record(tree_info.records,1,add_exp,up_lv)

    if check_task(tree_info.task_info) and not tree_info.rewarded then
        local item = get_tree_level_item(tree_level_conf,tree_info.level) 
        tree_info.shake_count = item.shake_count
        tree_info.rewarded = true
    end

    ntf_tree_info(tree_info,add_exp,fertilizer)

    local task_conf = get_task_conf(task_item.tree_task_id)
    local info = get_client_task_item(task_item,task_conf)

    return send_to_gateway('tree.RSP_TASK_REWARD', {result = error_code.RSP_SUCESS,info = info})
end

--领取完成所有任务奖励
function tree_handler.REQ_ALL_FINISH(msg)
    local uid = player.uid
    local tree_info = player.user_data.tree_info  

    check_reload_tree_task(tree_info)

    local tree_level_conf = global_configs.tree_level or {}
    local tree_item = get_tree_level_item(tree_level_conf,tree_info.level)  

    if tree_info.reward_status ~= 1 then
        return send_to_gateway('tree.RSP_ALL_FINISH', {result = error_code.RSP_SUCESS})
        
    end
    
    local coins = tree_item.coins

    local exinfo = {channel = player.channel,cur_channel = player.cur_channel}
    local ok,succ,ret = R().basesvr({key=uid}):call('.msg_handler','add_coins',uid,coins,reason.TREE,exinfo)
    if ok and succ and ret then
        tree_info.reward_status = 2
        notify_money_changed(uid,{coins = ret.curr})
        activity_player_number(uid)
        return send_to_gateway('tree.RSP_ALL_FINISH', {result = error_code.RSP_SUCESS,reward_status = tree_info.reward_status,coins = coins})
    end
    return send_to_gateway('tree.RSP_ALL_FINISH', {result = error_code.RSP_SUCESS})
end

--分享完成
function tree_handler.REQ_SHARE_FINISH(msg)
    local uid = player.uid
    local tree_info = player.user_data.tree_info  
    check_reload_tree_task(tree_info)
    local info = {}
    local type = msg.type
    finish_tree_task(tree_info,type,1,false,info)
    return send_to_gateway('tree.RSP_SHARE_FINISH', {result = error_code.RSP_SUCESS,info = info})
end

--摇钱树日志
function tree_handler.REQ_TREE_RECORD(msg)
    local tree_info = player.user_data.tree_info
    check_reload_tree_task(tree_info)
    local records = tree_info.records
    local ret = {} 
    -- dbglog(records)
    for i = #records,1,-1 do
        local v = records[i]
        local first = os.date("%Y-%m-%d  %H:%M  ",v.time)
        if v.type == 1 and v.up_lv then
           local second = string.format(tree_def.TREE_RECORD_ONE,v.add_exp or 0,v.up_lv or 0) 
           table_insert(ret,{ first = first , second = second})
        elseif v.type == 1 then
           local second = string.format(tree_def.TREE_RECORD_TWO,v.add_exp or 0) 
           table_insert(ret,{ first = first , second = second})
       end
    end
    
    return send_to_gateway('tree.RSP_TREE_RECORD',{record_list = ret})
end

--等级预览
function tree_handler.REQ_TREE_LEVEL_INFO(msg)
    local info = {}
    local tree_level_conf = global_configs.tree_level or {}
    for _,v in pairs(tree_level_conf) do
        local item = {
            level = v.level,
            shake_count = v.shake_count,
            max_coins = get_max_reward(v.rewards),
            reward_coins = v.coins,
            url = v.tree_url,
        }
        table_insert(info, item)
    end

    return send_to_gateway('tree.RSP_TREE_LEVEL_INFO', {result = error_code.RSP_SUCESS,info = info})
end

--获取帮助文本
function tree_handler.REQ_TREE_HELP(msg)
    local tree_conf = global_configs.tree_conf or {}
    return send_to_gateway('tree.RSP_TREE_HELP', {result = error_code.RSP_SUCESS,help_content = tree_conf.help_content})
end

-------------------------测试接口---------------------------------
--添加成长记录
local function add_tree_record(player,count)
    for i = 1,count do
        add_record(player.user_data.tree_info.records,1,200,2)
    end
end

--清理摇钱树信息
local function clear_tree_info(player)
    local tree_info = player.user_data.tree_info
    tree_info.exp = 0
    tree_info.level = 1
    reset_tree_task(tree_info)
end
--------------------------------------------------------
handler.register_module_handlers('tree',tree_handler)


local M = {
    reset_tree_task = reset_tree_task,        --重置摇钱树任务
    finish_tree_task = finish_tree_task,    --完成任务
    check_red_points = check_red_points,    --检查是否红点

    add_tree_record = add_tree_record,  --添加成长记录
    clear_tree_info = clear_tree_info,  --清理摇钱树信息
}

return M
